package com.hatch.ui {
	import com.hatch.utils.ImageUtil;
	import flash.display.Bitmap;
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLRequest;
	import flash.system.LoaderContext;	

	/**
	 * Image Loader Component that handles resizing and cropping
	 * 
     * @author David Knape
     */
    public class Image extends Component {
        
        // Events...
        public static const IMAGE_LOADED:String = "onImageLoaded";
        public static const IMAGE_ERROR:String = "onImageError";
        public static const IMAGE_PROGRESS:String = "onImageProgress";
		
		// Scale Modes...
		
		// Crop to fill height and width
		public static const SCALE_CROP:String = "crop";		
		// resize to height and width, but preserve aspect ratio
		public static const SCALE_RESIZE:String = "resize";		
		// no resize, height and width will always be that of loaded image
		public static const SCALE_NONE:String = "none";
		
		
		// private
		protected var _bitmap:Bitmap; 
        protected var _loader:Loader;
        protected var _url:String;
        protected var _imageLoaded:Boolean = false;
        protected var _scaleMode:String = SCALE_NONE;
		protected var _fadeOnLoad:Boolean = true;
		
		override protected function init() : void 
        {	          
        	//updateDelay = 0;
        	    	  	
            // create image _loader, setup on_imageLoaded listener, add to stage
            _loader = new Loader();
            _loader.contentLoaderInfo.addEventListener(Event.INIT, onImageLoaded, false, 0, true );
            _loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onImageProgress, false, 0, true);
            _loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onImageError, false, 0, true);
            addChild(_loader);
                                                
            super.init();
        }
        
        override public function draw() : void 
        { 	
        	 if(_imageLoaded)
        	 {
        		if(!image.visible)
        		{
        			image.alpha = 0;
        			image.visible = true;
        			image.alpha = 1;
        		}
        		imageBitmap.smoothing = true;
        		switch( scaleMode )
        		{
        			case SCALE_CROP: 	ImageUtil.crop( image, _width, _height); break;
        			case SCALE_RESIZE:	ImageUtil.resize( image, _width, _height, true ); break;        				
        		} 	
            }
		}
		
		public function get image () : DisplayObject 
		{
			if(_bitmap!=null) return _bitmap;
			else return _loader;
		}

		public function get imageBitmap() : Bitmap 
		{
        	if(_imageLoaded)
        	{
        		if(_url!=null) return _loader.content as Bitmap;
        		else return _bitmap; 
        	} else {
        		return null;
        	}
        }
		
        /**
         * Load the image
         */        
        public function load( image_url:String ):void 
        {  
        	if(image_url==_url) return;
           	if(_imageLoaded) unload();
           	_url = image_url;           	        
            if(_url!=null)
            {
              	_loader.load( new URLRequest(_url), new LoaderContext(true));
            }                
        }
        
        /**
         * Attach image from bitmap
         */        
        public function attach( bmp:Bitmap ):void {        
            if(_imageLoaded) unload();
            _bitmap = bmp;
            if(_bitmap!=null)
            {
                addChild(_bitmap);
                onImageLoaded();
            }
        }
                        
        /**
         * Once image is loaded, display it
         */
        private function onImageLoaded(e:Event=null):void 
        {   
        	_imageLoaded = true;         	
            //updateNow();
            //sendEvent( EVENT_LOADED, _url);  
            this.dispatchEvent( new Event(Image.IMAGE_LOADED) );     
        }
        
        /**
         * Progress Handler
         */
        private function onImageProgress(e:ProgressEvent=null):void 
        {    
            //sendEvent( EVENT_PROGRESS, e.bytesLoaded/e.bytesTotal );           
        }
        
        /**
         * Error handler
         */
        private function onImageError(e:IOErrorEvent=null):void 
        {    
            //sendEvent( EVENT_ERROR, e.text );           
        }
        
        /**
         * Unload image
         **/
        public function unload () : void 
        {            
            // hide
             //visible = false;
            _imageLoaded = false;
            if(image!=null) {
            	//FTween.stopTweening(image, 'alpha');
            	image.alpha = 0;
            	image.visible = false;
            }
            // unload
            try { _loader.close(); } catch ( e:Error ) {}
            try { _loader.unload(); } catch ( e2:Error ) {}
            
            if(_bitmap!=null && contains(_bitmap)) removeChild(_bitmap);            
		}
		
		//-------------------------------
		// GETTERS and SETTERS
		//-------------------------------
		

		public function get scaleMode():String {
			return _scaleMode;
		}
		
		public function set scaleMode(mode:String):void {
			_scaleMode = mode;
			invalidate();
		}

		override public function get width():Number
		{
			return (_imageLoaded && scaleMode!=SCALE_CROP ) ? image.width : _width;
		}		

		override public function get height():Number
		{
			return (_imageLoaded && scaleMode!=SCALE_CROP ) ? image.height : _height;
		} 
		
		public function get loaded () :Boolean {
			return _imageLoaded;
		}
		
		public function get fadeOnLoad() : Boolean {
			return _fadeOnLoad;
		}

		public function set fadeOnLoad(fadeIn : Boolean) : void {
			_fadeOnLoad=fadeIn;
		}
		
	}
}